package com.zkh.myutils.io.excel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import com.zkh.myutils.io.IOUtils;
import com.zkh.myutils.io.excel.worksheet.Cell;
import com.zkh.myutils.io.excel.worksheet.CellStyle;
import com.zkh.myutils.io.excel.worksheet.Row;
import com.zkh.myutils.io.excel.worksheet.Sheet;
import com.zkh.myutils.io.excel.worksheet.style.Align;
import com.zkh.myutils.io.excel.worksheet.style.Alignment;
import com.zkh.myutils.io.excel.worksheet.style.Font;
import com.zkh.myutils.utils.StringUtils;
import com.zkh.myutils.utils.Utils;
import com.zkh.myutils.utils.UtilsException;

/**
 * Excel辅助工具类
 * @author zkh
 */
public class ExcelUtils {
	
	/**
	 * 根据列字母获取当前列数
	 * @param columnLetter 列字母
	 * @return
	 */
	public static int getColumnNumber(String columnLetter) {
		//最终结果
		int res = 0;
		//分割字母
		char[] chars = columnLetter.toUpperCase().toCharArray();
		//遍历
		for(int i=0,len=chars.length; i<len; i++) {
			//当前编码
			int code = (int) chars[len-i-1] - 64;
			//累加
			res += code * Math.pow(26, i);
		}
		//返回结果
		return res;
	}
	
	/**
	 * 获取当前列对应的列字母
	 * @param columnNumber 当前列数
	 * @return
	 */
	public static String getColumnLetter(int columnNumber) {
		//每一位数字
		List<Integer> letterList = new ArrayList<>();
		//开始遍历
		while(columnNumber>26) {
			//取余数
			letterList.add(columnNumber%26);
			//取值
			columnNumber /= 26;
		}
		//末位数字
		letterList.add(columnNumber);
		//最终容器
		StringBuilder sb = new StringBuilder();
		//遍历，同时处理进位的总是
		for(int i=0,len=letterList.size(); i<len; i++) {
			//当前数字
			int c = letterList.get(i);
			//最后一位是0，则直接跳过
			if(i==len-1 && c==0) {
				continue;
			}
			//为0
			if(c==0) {
				//拼接Z
				c = 26;
				//前一位减1
				letterList.set(i+1, letterList.get(i+1)-1);
			}
			//拼接
			sb.append((char) (c + 64));
		}
		//返回
		return sb.reverse().toString();
	}
	
	/**
	 * 获取XLSX文件的ContentType
	 * @return
	 */
	public static String getContentType() {
		return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
	}
	
	/**
	 * 生成标准格式的excel数据
	 * @param sheetname sheet名称
	 * @param headers 数据字段名
	 * @param contents 数据
	 * @return
	 */
	public static WorkbookWriter createWorkbookWriter(String sheetname, List<String> headers, List<Object[]> contents){
		return createWorkbookWriter(sheetname, null, headers, contents);
	}
	
	/**
	 * 生成标准格式的excel数据
	 * @param sheetname sheet名称
	 * @param head Excel文件内标题
	 * @param headers 数据字段名
	 * @param contents 数据
	 * @return
	 */
	public static WorkbookWriter createWorkbookWriter(String sheetname, String head, List<String> headers, List<Object[]> contents) {
		//创建对象
		WorkbookWriter workbookWriter = new WorkbookWriter();
		//创建sheet
		Sheet sheet = workbookWriter.createSheet(sheetname);
	    //总列数
	    int len = headers.size();
	    //行
	    Row row = sheet.createRow();
	    //单元格
	    Cell cell;
    	//表头字体
    	Font font = new Font("宋体", true);
		//首行标题
	    if(!StringUtils.isEmpty(head)) {
	    	//表头样式
	    	CellStyle headstyle = new CellStyle();
	    	//字体
	    	headstyle.setFont(font);
	    	//对齐方式
	    	headstyle.setAlignment(new Alignment(Align.HORIZONTAL_CENTER, Align.VERTICAL_CENTER));
	    	//遍历列
	    	for(int i=0;i<len;i++) {
	    		//写入标题
	    		cell = row.createCell();
	    		cell.setCellValue(head);
	    		cell.setCellStyle(headstyle);
	    	}
	    	//合并
	    	sheet.addMerge(1, 1, 1, len);
	    	//创建新行
	    	row = sheet.createRow();
	    }
	    //表头样式
	    CellStyle titlestyle = new CellStyle();
	    //字体
	    titlestyle.setFont(font);
	    // 设置表头
	    for(int i=0;i<len;i++){
	    	cell = row.createCell();
	    	cell.setCellValue(headers.get(i));
	    	cell.setCellStyle(titlestyle);
	    }
	    //循环写入数据
	    for(Object[] cols: contents) {
	    	//创建行
	    	row = sheet.createRow();
	    	//遍历写数据
	    	for(int i=0;i<len;i++){
	    		cell = row.createCell();
	    		//数据
	    		Object temp = cols[i];
	    		//写入数据
	    		if(temp instanceof Number){
	    			cell.setCellValue(((Number) temp).doubleValue());
	    		}else if(temp!=null){
	    			cell.setCellValue(temp.toString());
	    		}
	    	}
	    }
		//返回
		return workbookWriter;
	}
	
	/**
	 * 将多个Excel对象压缩为一个ZIP包(JDK7以下压缩包内文件名会乱码)
	 * @param wbs Excel数据对象
	 * @param filename 每个Excel的文件名，与wbs一一对应。
	 * @return
	 */
	public static InputStream createZip(List<WorkbookWriter> wbs, List<String> filenames){
		//检测参数
		if(wbs==null || filenames==null || wbs.size()!=filenames.size()){
			throw new UtilsException("参数不能为null，且集合大小必须相同");
		}
		//声明变量
		File file = null;
		ZipOutputStream zos = null;
		OutputStream os = null;
		try{
			//创建临时文件
			file = File.createTempFile(Utils.getUUID(), null);
			//输出流
			os = new FileOutputStream(file);
			//zip流
			zos = new ZipOutputStream(os);
			//遍历
			for(int i=0,len=wbs.size();i<len;i++){
				//添加文件
				zos.putNextEntry(new ZipEntry(filenames.get(i)));
				//写入字节流
				wbs.get(i).write(zos);
			}
			//返回流
			return new FileInputStream(file);
		}catch(IOException e){
			throw new RuntimeException(e);
		} finally{
			//关闭流
			IOUtils.closeQuietly(zos, os);
			//删除临时文件
			if(file!=null) {
				file.deleteOnExit();
			}
		}
	}
}
